package mobilesmil.activity.composer;

import java.util.regex.Pattern;

import mobilesmil.activity.FileBrowserActivity;
import mobilesmil.activity.R;
import mobilesmil.data.SmilAudioResource;
import mobilesmil.data.SmilImageResource;
import mobilesmil.data.SmilRegion;
import mobilesmil.data.SmilResource;
import mobilesmil.data.SmilTextResource;
import mobilesmil.data.SmilVideoResource;
import mobilesmil.utils.FormValidationUtils;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

/**
 * Provides a form for editing of {@link SmilResource} properties, with different options depending on the type
 * of resource. All resources have Begin and End times. Non-audio resources have a "Position Region" button. {@link SmilTextResource}s have New
 * and Edit buttons for directly editing the content text files.
 * @author Ryan Ware
 *
 */
public class ResourcePropsFormActivity extends Activity {
	
	private EditText mEditSource;
	private EditText mEditBeginTime;
	private EditText mEditEndTime;
	private Button mBtnDone;
	private Button mBtnBrowse;
	private Button mBtnPosition;
	private Button mBtnNewText;
	private Button mBtnEditText;
	
	private SmilResource mEditingResource;
	private String mNewResourceType;
	private int mRegionHeight = 100;
	private int mRegionWidth = 100;
	private int mRegionTop = 0;
	private int mRegionLeft = 0;
	
	private static final byte REQUEST_CODE_BROWSE = 0;
	public static final byte REQUEST_CODE_EDIT_TEXT = 1;
	public static final byte REQUEST_CODE_EDIT_REGION = 2;
	
	private static final byte DIALOG_FORM_INVALID_ID = 0;
	private static String mDialogInvalidFormTitle = "";
	
	private static String mManagerTask, mBrowse, mFileType, mImage, mAudio, mText, mVideo;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
		 super.onCreate(savedInstanceState);
	     setContentView(R.layout.properties_form_resource);
	     mEditingResource = ComposerActivity.getEditingResource();
	     mNewResourceType = ComposerActivity.getNewResourceType();
	     
	     mManagerTask = this.getString(R.string.managerTask);
	     mBrowse = this.getString(R.string.browse);
	     mFileType = this.getString(R.string.fileType);
	     mImage = this.getString(R.string.image);
	     mAudio = this.getString(R.string.audio);
	     mText = this.getString(R.string.text);
	     mVideo = this.getString(R.string.video);
	     
        mEditSource = (EditText)findViewById(R.id.editSource);
        mEditBeginTime = (EditText)findViewById(R.id.editBeginTime);
        mEditEndTime = (EditText)findViewById(R.id.editEndTime);
        
        mBtnDone = (Button)findViewById(R.id.btnResourceDone);
        mBtnBrowse = (Button)findViewById(R.id.btnResourceBrowse);
        mBtnPosition = (Button)findViewById(R.id.btnResourcePosition);
        mBtnNewText = (Button)findViewById(R.id.btnTextResourceNew);
        mBtnEditText = (Button)findViewById(R.id.btnTextResourceEdit);
              
        updateFormFields();
	        
        mBtnBrowse.setOnClickListener(new View.OnClickListener() {
        	public void onClick(View view) {
        		// send Intent to FileBrowserActivity to browse for files
        		Intent managerIntent = new Intent(getApplicationContext(), FileBrowserActivity.class);
        		managerIntent.putExtra(mManagerTask, mBrowse);
        		
        		String type = "";
        		if(mEditingResource != null) {
        			type = mEditingResource.getType();
        		} else if(mNewResourceType != null) {
        			type = mNewResourceType;
        		}
        		
        		if(type.equalsIgnoreCase(SmilResource.TYPE_AUDIO))
        			managerIntent.putExtra(mFileType, mAudio);
        		else if(type.equalsIgnoreCase(SmilResource.TYPE_IMAGE))
        			managerIntent.putExtra(mFileType, mImage);
        		else if(type.equalsIgnoreCase(SmilResource.TYPE_TEXT))
        			managerIntent.putExtra(mFileType, mText);
        		else if(type.equalsIgnoreCase(SmilResource.TYPE_VIDEO))
        			managerIntent.putExtra(mFileType, mVideo);
        		
        		startActivityForResult(managerIntent, REQUEST_CODE_BROWSE);
        	}
        });
	        
        mBtnPosition.setOnClickListener(new View.OnClickListener() {
        	public void onClick(View view) {
        		editResource();
        		openRegionPositioningActivity();
        	}
        });
        
        mBtnDone.setOnClickListener(new View.OnClickListener() {
        	public void onClick(View view) {
        		if(fieldsAreValid()) {
	        		editResource();
	        		setResult(RESULT_OK, getIntent());
	        		finish();
        		}
        		else {
        			showDialog(DIALOG_FORM_INVALID_ID);
        		}
        	}
        });

        mBtnNewText.setOnClickListener(new View.OnClickListener() {
        	public void onClick(View view) { // opens EditTextResourceActivity for creating a new file
        		Intent editTextResourceIntent = new Intent(getApplicationContext(), EditTextResourceActivity.class);
        		editTextResourceIntent.putExtra("newOrEdit", "new");
        		startActivityForResult(editTextResourceIntent, REQUEST_CODE_EDIT_TEXT);
        	}
        });
        
        mBtnEditText.setOnClickListener(new View.OnClickListener() {
        	public void onClick(View view) { // opens EditTextResourceActivity for editing an existing new file
        		Intent editTextResourceIntent = new Intent(getApplicationContext(), EditTextResourceActivity.class);
        		editTextResourceIntent.putExtra("newOrEdit", "edit");
        		editTextResourceIntent.putExtra("textFileName", mEditSource.getText().toString());
        		startActivityForResult(editTextResourceIntent, REQUEST_CODE_EDIT_TEXT);
        	}
        });
        
	}

	@Override
	public void onResume() {
		super.onResume();
		updateFormFields();
	}
	
	/**
	 * Ensures user input fields contain valid values.
	 * @return true if all user input fields are valid, false if any are not
	 */
	private boolean fieldsAreValid() {
		String source = mEditSource.getText().toString();
		String beginTime = mEditBeginTime.getText().toString();
		String endTime = mEditEndTime.getText().toString();
		String integerRegex = FormValidationUtils.INTEGER_REGEX;
		
		if(source == null || source.length() == 0) {
			mDialogInvalidFormTitle = "Please select a source file.";
			return false;
		}
			
		if(Pattern.matches(integerRegex, beginTime) && Pattern.matches(integerRegex, endTime)) {
			if(Integer.valueOf(beginTime) > Integer.valueOf(endTime)) {
				mDialogInvalidFormTitle = "Begin time cannot be larger than end time.";
				return false;
			}
			else
				return true;
		}
		mDialogInvalidFormTitle = "Begin and end times must be nonnegative integer values.";
		return false;
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		super.onCreateDialog(id);
		Dialog dialog = null;
		switch(id)
		{
			case DIALOG_FORM_INVALID_ID:
		        dialog = FormValidationUtils.createInvalidFormDialog(this);
		        dialog.setTitle(mDialogInvalidFormTitle);
				break;
		}
		return dialog;
	}
	
	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		super.onPrepareDialog(id, dialog);
		switch(id)
		{
			case DIALOG_FORM_INVALID_ID:
				dialog.setTitle(mDialogInvalidFormTitle);
				break;
		}
	}
	
	/**
	 * Updates the form fields by pulling relevant data from the {@link SmilResource} being edited.
	 */
	private void updateFormFields() {
        mEditSource.setEnabled(false);
        
		if(!ComposerActivity.isCreatingNewResource() && mEditingResource != null)
        { // user is editing an existing resource
			if(!mEditingResource.getType().equals(SmilResource.TYPE_TEXT)) {
	        	hideComponentsForNonText();
	        	
	        	if(mEditingResource.getType().equals(SmilResource.TYPE_AUDIO)) {
		        	hideComponentsForAudio();
		        }
	        }
			// update form fields with values from editing data set
        	mEditSource.setText(mEditingResource.getSource());
	        mEditBeginTime.setText(String.valueOf(mEditingResource.getBeginTime()));
	        mEditEndTime.setText(String.valueOf(mEditingResource.getEndTime()));
	        
	        Rect editingRegionRect = mEditingResource.getSmilRegion().getRect();
	        mRegionHeight = editingRegionRect.height();
	        mRegionWidth = editingRegionRect.width();
	        mRegionTop = editingRegionRect.top;
	        mRegionLeft = editingRegionRect.left;

        }
        else // creating a new resource
        {
        	if(mNewResourceType != null) 
        	{
        		if(!mNewResourceType.equals(SmilResource.TYPE_TEXT)) 
        		{
        			hideComponentsForNonText();
        			
	        		if(mNewResourceType.equals(SmilResource.TYPE_AUDIO)) 
	        		{
	        			hideComponentsForAudio();
	            	}
        		}
        		else { // text resource
        			if(mEditSource.getText().toString().length() == 0)
        					mBtnEditText.setVisibility(View.INVISIBLE);
    				else
    					mBtnEditText.setVisibility(View.VISIBLE);
        		}
        	}
        }
		
		if(mEditSource.getText().toString().length() == 0)
			mBtnEditText.setVisibility(View.INVISIBLE);
	}
	/**
	 * Do not show form fields that apply only to {@link SmilTextResource}s. These are the New and Edit buttons.
	 */
	private void hideComponentsForNonText() {
    	mBtnNewText.setVisibility(View.INVISIBLE);
    	mBtnEditText.setVisibility(View.INVISIBLE);
	}
	/**
	 * Hide the "Position Region" button as it does not apply to {@link SmilAudioResource}s.
	 */
	private void hideComponentsForAudio() {
    	mBtnPosition.setVisibility(View.GONE);
	}
	
	@Override
	public void onBackPressed() {
		if(ComposerActivity.isCreatingNewResource()) { // if creating new SMIL file, will send user back to AddNewResourceActivity
			setResult(ComposerActivity.RESULT_CODE_NEW_BACK_BUTTON);
		}
		finish();
	}
	
	/**
	 * The editing {@link SmilDataSet} is updated with all of the values entered into the form fields and from the {@link RegionPositioningActivity}.
	 */
	private void editResource() {
		String source = mEditSource.getText().toString();
		int beginTime = Integer.valueOf(mEditBeginTime.getText().toString());
		int endTime = Integer.valueOf(mEditEndTime.getText().toString());
		
		if(!ComposerActivity.isCreatingNewResource()) // update begin and end times and refresh data set lists
		{ 
    		mEditingResource.setBeginTime(beginTime);
    		mEditingResource.setEndTime(endTime);
    		ComposerActivity.refreshDataSet();
		}
		
		if(ComposerActivity.isCreatingNewResource()) // adding a new resource, must create the Resource and Region
		{ 
			SmilRegion region = new SmilRegion(ComposerActivity.generateUniqueRegionId(), 
					mRegionLeft, mRegionTop, mRegionLeft + mRegionWidth, mRegionTop + mRegionHeight);
			
			if(mNewResourceType.equalsIgnoreCase("audio")) {
        		mEditingResource = new SmilAudioResource(source, region, beginTime, endTime);
        	}
        	else if(mNewResourceType.equalsIgnoreCase("img")) {
        		mEditingResource = new SmilImageResource(source, region, beginTime, endTime);
        	}
        	else if(mNewResourceType.equalsIgnoreCase("text")) {
        		mEditingResource = new SmilTextResource(source, region, beginTime, endTime);
        	}
        	else if(mNewResourceType.equalsIgnoreCase("video")) {
        		mEditingResource = new SmilVideoResource(source, region, beginTime, endTime);
        	}
			ComposerActivity.setEditingResource(mEditingResource);
    		ComposerActivity.addNewResource(mEditingResource);
		}
		ComposerActivity.setCreatingNewResource(false);
		ComposerActivity.setCreatingNewSmil(false); // a resource has now been added, so cannot be creating a new file anymore
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
		super.onActivityResult(requestCode, resultCode, intent);
		Bundle properties = null;
		if(intent != null)
			properties = intent.getExtras();
		
		switch(requestCode)
		{
	        case REQUEST_CODE_BROWSE:
		        switch(resultCode)
		        {
		        	case RESULT_OK:
		        		if(properties != null) { // new file name from FileBrowserActivity
		        			mEditSource.setText(properties.getString("fileName"));
		        		}
		        		break;
		        		
		        	default:
		        		break;
		        }
		        break;
	        
	        case REQUEST_CODE_EDIT_TEXT:
	        	switch(resultCode)
	        	{
		        	case RESULT_OK:
		        		if(properties != null) { // new text file name from EditTextResourceActivity
			        		mEditSource.setText(properties.getString("newTextSource"));
		        		}
		        		break;
		        		
		        	default:
		        		break;
	        	}
	        	break;
	        case REQUEST_CODE_EDIT_REGION:
	        	switch(resultCode)
	        	{
		        	case RESULT_OK:
		        		if(properties != null) { // new Region parameters from RegionPositioningActivity
		        			mRegionHeight = Integer.parseInt(properties.getString("regionHeight"));
		        			mRegionWidth = Integer.parseInt(properties.getString("regionWidth"));
		        			mRegionTop = Integer.parseInt(properties.getString("regionTop"));
		        			mRegionLeft = Integer.parseInt(properties.getString("regionLeft"));
		        		}
		        		break;
		        		
		        	default:
		        		break;
	        	}
	        	break;
		}
	}
	
	/**
	 * Starts {@link RegionPositioningActivity}.
	 */
	private void openRegionPositioningActivity() {
		Intent resourcePositioningIntent = new Intent(getApplicationContext(), RegionPositioningActivity.class);
		startActivity(resourcePositioningIntent);
	}

}
